package cn.com.zero.file.service;

import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.constraints.NotNull;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;

/**
 * @author liuxh
 * @version 1.0.0
 * @Description 自定义 MultipartFile 实现类
 * @createTime 2023/2/27 16:21
 */
public class ZeroMultipartFile implements MultipartFile {

    /**
     * 文件名
     */
    private String name;

    /**
     * 真实文件名
     */
    private String originalFilename;

    /**
     * 内容类型
     */
    @Nullable
    private String contentType;

    /**
     * 数据 byte 数组
     */
    private byte[] content;


    /**
     * 构造方法
     *
     * @param name    文件名称
     * @param content 文件 byte 数组
     */
    public ZeroMultipartFile(@NotNull String name, @NotNull byte[] content) {
        this(name, null, null, content);
    }

    /**
     * 构造方法
     *
     * @param name          文件名称
     * @param contentStream 内容输入流
     * @throws IOException 读取流信息抛出异常
     */
    public ZeroMultipartFile(String name, InputStream contentStream) throws IOException {
        this(name, null, null, FileCopyUtils.copyToByteArray(contentStream));
    }

    /**
     * 构造方法
     *
     * @param name             文件名称
     * @param originalFilename 真实文件名
     * @param contentType      文件类型
     * @param contentStream    内容输入流
     * @throws IOException 读取流信息抛出异常
     */
    public ZeroMultipartFile(String name, @Nullable String originalFilename, @Nullable String contentType, InputStream contentStream) throws IOException {
        this(name, originalFilename, contentType, FileCopyUtils.copyToByteArray(contentStream));
    }

    /**
     * 构造方法
     *
     * @param name             文件名称
     * @param originalFilename 真实文件名
     * @param contentType      文件类型
     * @param content          文件 byte 数组
     */
    public ZeroMultipartFile(String name, @Nullable String originalFilename, @Nullable String contentType, @Nullable byte[] content) {
        Assert.hasLength(name, "Name must not be null");
        this.name = name;
        this.originalFilename = originalFilename != null ? originalFilename : name;
        this.contentType = contentType;
        this.content = content != null ? content : new byte[0];
    }

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public String getOriginalFilename() {
        return this.originalFilename;
    }

    @Override
    public String getContentType() {
        return this.contentType;
    }

    @Override
    public boolean isEmpty() {
        return this.content == null || this.content.length == 0;
    }

    @Override
    public long getSize() {
        if (this.content == null) {
            return 0L;
        }
        return this.content.length;
    }

    @Override
    public byte[] getBytes() {
        return this.content;
    }

    @Override
    public InputStream getInputStream() {
        return new ByteArrayInputStream(this.content);
    }

    @Override
    public void transferTo(File file) throws IOException, IllegalStateException {
        FileCopyUtils.copy(this.content, file);
    }
}
